﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace phoneGet
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Icon = System.Drawing.Icon.ExtractAssociatedIcon(Application.ExecutablePath);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitPhonedata();
        }

        private string foldPath = AppDomain.CurrentDomain.BaseDirectory + "//批量号码生成";  //默认路径
        private static byte[] buf; //存储所有的数据于byte[]中
        private static byte[] version = new byte[4];

        private List<Province> provinceList = new List<Province>();
        private List<string> phoneList = new List<string>();

        private string prefix = "好友";
        private string group = "大吉大利";
        private string note = "今晚吃鸡";

        private bool isUsingAllNumber = true;
        private bool isUsingPrefix = false;
        private bool isUsingGroup = false;
        private bool isUsingNote = false;
        private bool isOnlyPrefix = false;
        private bool isAloneFile = false;

        // 运营商类型:
        // 1 移动
        // 2 联通
        // 3 电信
        // 4 电信虚拟运营商
        // 5 联通虚拟运营商
        // 6 移动虚拟运营商
        private string GetCardType(byte code)
        {
            int type = Convert.ToInt32(code);
            string tmp = "";
            switch (type)
            {
                case 1:
                    tmp = "中国移动";
                    break;

                case 2:
                    tmp = "中国联通";
                    break;

                case 3:
                    tmp = "中国电信";
                    break;

                case 4:
                    tmp = "电信虚拟运营商";
                    break;

                case 5:
                    tmp = "联通虚拟运营商";
                    break;

                case 6:
                    tmp = "中国移动虚拟运营商";
                    break;

                default:
                    tmp = "未知电信运营商";
                    break;
            }
            return tmp;
        }

        public class PhoneInfo
        {
            public string  phone7;  //号段
            public byte  home;  //运营商
        }

        public class Province
        {
            public string name { get; set; }
            public List<City> cityList = new List<City>();
        }


        public class City
        {
            public string name { get; set; }
            public string zipCode;   //邮编
            public string areaCode;    //区号
            public int startOff;  //索引
            public int endOff;  //索引
        }



        private void InitPhonedata()
        {
            string FileName = "phonehome.dat";
            if (!File.Exists(FileName))
            {
                labelStatus.Text = "数据丢失，加载失败！";
                return;
            }

            using (FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read))
            {
                buf = new byte[fs.Length];
                fs.Read(buf, 0, (int)fs.Length);   //读入缓存
            }

            
            for (int i = 0; i < 4; ++i)
            {
                version[i] = buf[i];
            }
            Console.WriteLine("当前版本为：" + Encoding.UTF8.GetString(version));

            int startOff;
            startOff = buf[6] | buf[5] << 8 | buf[4] << 16;
            Console.WriteLine(startOff);
            int phoneOff = startOff - 4;
            int endOff = 0;
            for (int i = 8,n = 0; i < phoneOff; )
            {
                List<byte> pr = new List<byte>();
                while (buf[i] != 0x7c || n < 3)
                {
                    if(buf[i] == 0x7c)
                    {                        
                        ++n;
                    }

                    pr.Add(buf[i]);
                    ++i;
                }

                endOff = buf[i + 1] << 16 | buf[i + 2] << 8 | buf[i + 3];
                string str = Encoding.UTF8.GetString(pr.ToArray());   //解码
                string[] strArray = str.Split('|');

                int index = -1;
                try
                {
                    index = provinceList.FindIndex(a => a.name == strArray[0]);
                }
                catch
                {
                    Province pp = new Province();
                    pp.name = strArray[0];
                    provinceList.Add(pp);
                    index = provinceList.FindIndex(a => a.name == strArray[0]);
                }

                if (index == -1)
                {
                    Province pp = new Province();
                    pp.name = strArray[0];
                    provinceList.Add(pp);
                    index = provinceList.FindIndex(a => a.name == strArray[0]);
                }

                City cc = new City();
                cc.name = strArray[1];
                cc.zipCode = strArray[2];
                cc.areaCode = strArray[3];
                cc.startOff = startOff;
                cc.endOff = endOff;                                                          
                provinceList[index].cityList.Add(cc);

                startOff = endOff;
                i += 5;
                n = 0;

                if (buf[i] == 0x7f && buf[i + 1] == 0x7f
                    && buf[i + 2] == 0x7f && buf[i + 3] == 0x7f)
                {
                    //Console.WriteLine(i.ToString());
                    break;
                }
            }

            comboBoxProvince.DataSource = provinceList;
            comboBoxProvince.DisplayMember = "name";
        }

        private void comboBoxProvince_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxProvince.SelectedIndex < 0)
                return;

            comboBoxCity.DataSource = ((Province)comboBoxProvince.SelectedItem).cityList;
            comboBoxCity.DisplayMember = "name";
        }

        private void comboBoxCity_SelectedIndexChanged(object sender, EventArgs e)
        {
            City cc = comboBoxCity.SelectedItem as City;
            phoneList.Clear();
            listBoxPhone7.Items.Clear();
            for (int i = cc.startOff; i < cc.endOff; i += 4)
            {
                int phone7 = buf[i] << 16 | buf[i + 1] << 8 | buf[i + 2];
                listBoxPhone7.Items.Add(phone7.ToString());
            }
            int off = cc.endOff - cc.startOff;
            int count = off / 4;
            textBoxCount.Text = count.ToString();

            labelStatus.Text = "共加载" + listBoxPhone7.Items.Count + "个号段";
        }

        private void labelAddSelect_Click(object sender, EventArgs e)
        {
            if (listBoxPhone7.SelectedItems.Count > 0)
            {
                foreach (var item in listBoxPhone7.SelectedItems)
                {
                    if (!listBoxSelect.Items.Contains(item))
                    {
                        listBoxSelect.Items.Add(item);
                    }
                }             
            }

            labelStatus.Text = "已选择" + listBoxSelect.Items.Count + "个号段";
        }

        private void labelDelSelect_Click(object sender, EventArgs e)
        {
            while(listBoxSelect.SelectedItems.Count > 0)
            {
                listBoxSelect.Items.Remove(listBoxSelect.SelectedItem);                  
            }

            labelStatus.Text = "已选择" + listBoxSelect.Items.Count + "个号段";
        }

        private void textBoxBuildCount_Enter(object sender, EventArgs e)
        {
            labelStatus.Text = "请输入1 - 10000 的数值";
        }

        private void textBoxBuildCount_Leave(object sender, EventArgs e)
        {
            string str = textBoxGenerateCount.Text;
            string reg = @"^[1-9]\d{0,3}|10000$";
            if (!Regex.IsMatch(str, reg))
            {
                labelStatus.Text = "数值错误，请重新输入！";
                textBoxGenerateCount.Clear();
                this.ActiveControl = textBoxGenerateCount;
            }
        }

        private void linkLabelProject_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://gitee.com/jiangjianghu/phonenumbergenerate");
        }

        private void linkLabelReward_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("https://s1.ax1x.com/2020/09/06/wevUr8.md.png");
        }


        private void checkBoxIsAloneFile_CheckedChanged(object sender, EventArgs e)
        {
            isAloneFile = checkBoxIsAloneFile.Checked;
        }

        private void checkBoxIsOnlyPrefix_CheckedChanged(object sender, EventArgs e)
        {
            isOnlyPrefix = checkBoxIsOnlyPrefix.Checked;
            if (checkBoxIsOnlyPrefix.Checked)
            {
                checkBoxIsUsingPrefix.Checked = true;
                isUsingPrefix = true;
            }
        }

        private void checkBoxIsUsingPrefix_CheckedChanged(object sender, EventArgs e)
        {
            isUsingPrefix = checkBoxIsUsingPrefix.Checked;
            if (!checkBoxIsUsingPrefix.Checked)
            {
                checkBoxIsOnlyPrefix.Checked = false;
                isOnlyPrefix = false;
            }
        }

        private void checkBoxIsUsingGroup_CheckedChanged(object sender, EventArgs e)
        {
            isUsingGroup = checkBoxIsUsingGroup.Checked;
        }

        private void checkBoxIsUsingNote_CheckedChanged(object sender, EventArgs e)
        {
            isUsingNote = checkBoxIsUsingNote.Checked;
        }


        private void buttonGenerate_Click(object sender, EventArgs e)
        {
            string str = textBoxGenerateCount.Text;
            int numGenerate;
            string reg = @"^[1-9]\d{0,3}|10000$";
            if (!Regex.IsMatch(str, reg))
            {
                labelStatus.Text = "数值错误，请重新输入！";
                textBoxGenerateCount.Clear();
                this.ActiveControl = textBoxGenerateCount;
                return;
            }
            else
            {
                numGenerate = Convert.ToInt32(str);
            }

            if (listBoxSelect.Items.Count <= 0)
            {
                labelStatus.Text = "请选择需要生成号码的字段！";
                return;
            }

            FolderBrowserDialog sfd = new FolderBrowserDialog();
            sfd.Description = "请选择文件路径";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                foldPath = sfd.SelectedPath + "//批量号码生成";
            }
            else
            {
                return;
            }

            if (!Directory.Exists(foldPath))
            {
                Directory.CreateDirectory(foldPath);
            }

            prefix = String.IsNullOrEmpty(textBox1.Text) ? "好友" : textBox1.Text;
            group = String.IsNullOrEmpty(textBox2.Text) ? "今晚吃鸡" : textBox2.Text;
            note = String.IsNullOrEmpty(textBox3.Text) ? "大吉大利" : textBox3.Text;
            isUsingAllNumber = radioButtonAllNumber.Checked;

            if (isAloneFile)  // 每个号段生成单独文件
            {
                foreach (var item in listBoxSelect.Items)
                {
                    string FileName = foldPath + $"//批量生成{item}.vcf";
                    if (File.Exists(FileName))
                    {
                        FileStream fs = new FileStream(FileName, FileMode.Truncate, FileAccess.ReadWrite);//清空文件内容
                        fs.Close();
                    }

                    using (StreamWriter sw = new StreamWriter(FileName, true, new UTF8Encoding(false)))
                    {
                        string text = "";
                        GenerateText(item, numGenerate, ref text);

                        text = text.TrimEnd('\r', '\n');
                        sw.Write(text);
                    }
                }
            }
            else
            {
                string FileName = foldPath + $"//批量生成.vcf";
                if (File.Exists(FileName))
                {
                    FileStream fs = new FileStream(FileName, FileMode.Truncate, FileAccess.ReadWrite);//清空文件内容
                    fs.Close();
                }

                using (StreamWriter sw = new StreamWriter(FileName, true, new UTF8Encoding(false)))
                {                    
                    foreach (var item in listBoxSelect.Items)
                    {
                        string text = "";
                        GenerateText(item, numGenerate, ref text);

                        if (item.Equals(listBoxSelect.Items[listBoxSelect.Items.Count-1]))
                        {
                            text = text.TrimEnd('\r', '\n');
                        }

                        sw.Write(text);
                    }
                }
            }

            labelStatus.Text = "已生成" + listBoxSelect.Items.Count + "个文件，共计" + listBoxSelect.Items.Count* numGenerate + "个号码";
        }


        void GenerateText(Object item, int numGenerate, ref string text)
        {
            Random rd = new Random();
            List<string> Phonelist = new List<string>();
            if (numGenerate > 5000)
            {
                int surplusNum = 10000 - numGenerate;
                List<string> surplusPhonelist = new List<string>();
                for (int i = 0; i < surplusNum; ++i)
                {
                    int number = rd.Next(0, 9999);
                    string phonenum = string.Format("{0:D4}", number);
                    if (!surplusPhonelist.Contains(phonenum))//集合list不包含num，就把num添加进list。这样保证不重复
                    {
                        surplusPhonelist.Add(phonenum);
                    }
                    else
                    {
                        i--;
                        continue;
                    }
                }

                for (int i = 0; i < 10000; ++i)
                {
                    string num = string.Format("{0:D4}", i);
                    if (!surplusPhonelist.Contains(num))
                    {
                        Phonelist.Add(item + num);
                    }                  
                }                
            }
            else
            {
                for (int i = 0; i < numGenerate; ++i)
                {
                    int number = rd.Next(0, 9999);
                    string phonenum = item + string.Format("{0:D4}", number);
                    if (!Phonelist.Contains(phonenum))//集合list不包含num，就把num添加进list。这样保证不重复
                    {
                        Phonelist.Add(phonenum);
                    }
                    else
                    {
                        i--;
                        continue;
                    }
                }
            }            
            
            for (int i = 0; i < numGenerate; ++i)
            {   
                text += "BEGIN:VCARD" + "\r\n";
                text += "VERSION:2.1" + "\r\n";

                //姓名
                string name = isUsingAllNumber ? Phonelist[i] : item as string;
                if (isOnlyPrefix)
                {
                    text += "FN:" + prefix + "\r\n";
                    text += "N:;" + prefix + ";;;" + "\r\n";
                }
                else if (isUsingPrefix)
                {
                    text += "FN:" + prefix + name + "\r\n";
                    text += "N:;" + prefix + name + ";;;" + "\r\n";
                }
                else
                {
                    text += "FN:" + name + "\r\n";
                    text += "N:;" + name + ";;;" + "\r\n";
                }

                //备注
                if (isUsingNote)
                {
                    text += "NOTE:" + note + "\r\n";
                }

                text += "TEL;CELL:" + Phonelist[i] + "\r\n";

                //群组
                if (isUsingGroup)
                {
                    text += "X-GROUP-MEMBERSHIP:" + group + "\r\n";
                }

                text += "END:VCARD" + "\r\n";
            }
        }

    }
}
